// autoupdate
package autoupdate

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"math/rand"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"
)

type AutoUpdate struct {
	Url      string //下载路径
	Softname string //软件名
	CurrVer  string //当前版本
	CurrName string //当前运行路径及文件名
}

func (au *AutoUpdate) Update() error {
	if strings.HasSuffix(au.CurrName, "update.exe") { //开始更新
		time.Sleep(3 * time.Second)
		if au.copyFile() {
			cmd := exec.Command("cmd", "/c", "start", filepath.Dir(au.CurrName)+"\\"+au.Softname+".exe")
			cmd.Start()
			cmd.Wait()
			os.Exit(0)
		}
	} else { //检测更新

		//		fmt.Println("远端版本号:", newVer)
		//		fmt.Println("本地版本号:", au.CurrVer)
		if au.HaveNewVer() {
			if err := au.getNewVer(); err != nil {
				return err
			} else {
				cmd := exec.Command("cmd", "/c", "start", filepath.Dir(au.CurrName)+"\\update.exe")
				cmd.Start()
				cmd.Wait()
				os.Exit(0)
			}
		} else {
			os.Remove("update.exe")
		}
	}
	return nil
}

func (au *AutoUpdate) HaveNewVer() bool {
	resp, err := http.Get(au.Url + "/" + au.Softname + ".txt?num=" + fmt.Sprintf("%d", rand.Intn(1000)))
	if err != nil {
		return false
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return false
	}
	newVer := string(body)
	if strings.Index(newVer, "404 page not found") != -1 {
		return false
	}
	return newVer != au.CurrVer
}
func (au *AutoUpdate) getNewVer() error {
	client := http.Client{Timeout: 900 * time.Second}
	resp, err := client.Get(au.Url + "/" + au.Softname + ".exe?num=" + fmt.Sprintf("%d", rand.Intn(1000)))
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.Status == "200 OK" {
		newFile, err := os.Create("update.exe")
		if err != nil {
			return err
		}
		defer newFile.Close()

		_, err = io.Copy(newFile, resp.Body)
		if err != nil {
			return err
		}
		return nil
	} else {
		return errors.New(resp.Status)
	}

}

func (au *AutoUpdate) copyFile() bool {
	source_open, err := os.Open(au.CurrName)
	if err != nil {
		return false
	}
	defer source_open.Close()
	dest_open, err := os.OpenFile(filepath.Dir(au.CurrName)+"\\"+au.Softname+".exe", os.O_CREATE|os.O_WRONLY, 644)
	if err != nil {
		return false
	}
	defer dest_open.Close()
	//进行数据拷贝
	_, copy_err := io.Copy(dest_open, source_open)
	if copy_err != nil {
		return false
	} else {
		return true
	}
}
